/*
 * Copyright 2019 Flipkart Internet Pvt. Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.flipkart.ohos.proteus;

import ohos.app.AbilityContext;

import com.flipkart.ohos.proteus.value.Layout;
import com.flipkart.ohos.proteus.value.Value;

import java.util.Map;

/**
 * ProteusContext
 *
 * @author aditya.sharat
 */
public class ProteusContext extends AbilityContext {
    public AbilityContext context;

    private ProteusLayoutInflater inflater;

    private final ProteusResources resources;

    private final ProteusLayoutInflater.Callback callback;

    private final ProteusLayoutInflater.ImageLoader loader;

    ProteusContext(AbilityContext base, ProteusResources resources,
                   ProteusLayoutInflater.ImageLoader loader,
                   ProteusLayoutInflater.Callback callback) {
        super(base);
        this.context = base;
        this.callback = callback;
        this.loader = loader;
        this.resources = resources;
    }

    public ProteusLayoutInflater.Callback getCallback() {
        return callback;
    }

    public FunctionManager getFunctionManager() {
        return resources.getFunctionManager();
    }

    public Function getFunction(String name) {
        return resources.getFunction(name);
    }

    public Layout getLayout(String name) {
        return resources.getLayout(name);
    }

    public ProteusLayoutInflater.ImageLoader getLoader() {
        return loader;
    }

    public ProteusLayoutInflater getInflater(IdGenerator idGenerator) {
        if (null == this.inflater) {
            this.inflater = new SimpleLayoutInflater(this, idGenerator);
        }
        return this.inflater;
    }

    public ProteusLayoutInflater getInflater() {
        return getInflater(new SimpleIdGenerator());
    }

    public ViewTypeParser getParser(String type) {
        return resources.getParsers().get(type);
    }

    public ProteusResources getProteusResources() {
        return resources;
    }

    public Map<String, Value> getStyle(String name) {
        return resources.getStyle(name);
    }

    /**
     * Builder
     *
     * @author adityasharat
     */
    public static class Builder {
        private final AbilityContext base;

        private final FunctionManager functionManager;

        private final Map<String, ViewTypeParser> parsers;

        private ProteusLayoutInflater.ImageLoader loader;

        private ProteusLayoutInflater.Callback callback;

        private LayoutManager layoutManager;

        private StyleManager styleManager;

        Builder(AbilityContext context, Map<String, ViewTypeParser> parsers, FunctionManager functionManager) {
            this.base = context;
            this.parsers = parsers;
            this.functionManager = functionManager;
        }

        public Builder setImageLoader(ProteusLayoutInflater.ImageLoader loader) {
            this.loader = loader;
            return this;
        }

        public Builder setCallback(ProteusLayoutInflater.Callback callback) {
            this.callback = callback;
            return this;
        }

        public Builder setLayoutManager(LayoutManager layoutManager) {
            this.layoutManager = layoutManager;
            return this;
        }

        public Builder setStyleManager(StyleManager styleManager) {
            this.styleManager = styleManager;
            return this;
        }

        public ProteusContext build() {
            ProteusResources resources = new ProteusResources(parsers, layoutManager, functionManager, styleManager);
            return new ProteusContext(base, resources, loader, callback);
        }
    }
}
